﻿using RndMaterialDisposalService.Attrbutes;
using RndMaterialDisposalService.Controllers;
using RndMaterialDisposalService.Models;
using RndMaterialDisposalService.Models.Entitys;
using RndMaterialDisposalService.Repository;
using RndMaterialDisposalService.Services.Interface;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace RndMaterialDisposalService.Services
{
    /// <summary>
    /// 
    /// </summary>
    [NAutowired(Lifecycle.Scoped)]
    public class SMOService : ISMOService
    {
        private WorkflowCommonDataContext dbContext;
        private UserBaseInforDataContext dbUserBaseContext;
        private IUserInfoService userInfoService;
        private EDPPlatformContext edpContext;
        private EDPApplicationContext edpApplicationContext;
        private readonly ILogger<SMOService> logger;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_dbContext"></param>
        /// <param name="_dbUserBaseContext"></param>
        /// <param name="_edpContext"></param>
        /// <param name="_edpApplicationContext"></param>
        /// <param name="_userInfoService"></param>
        /// <param name="_logger"></param>
        public SMOService(WorkflowCommonDataContext _dbContext, 
            UserBaseInforDataContext _dbUserBaseContext, 
            EDPPlatformContext _edpContext, 
            EDPApplicationContext _edpApplicationContext, 
            IUserInfoService _userInfoService,
            ILogger<SMOService> _logger)
        {
            dbContext = _dbContext;
            dbUserBaseContext = _dbUserBaseContext;
            userInfoService = _userInfoService;
            edpContext = _edpContext;
            edpApplicationContext = _edpApplicationContext;
            logger = _logger;   
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <returns></returns>
        public async Task<ApplicationDataModel> GetApplicationData(string procInstId)
        {
            return await dbContext.ApplicationData.FirstOrDefaultAsync(p => p.ProcInstId == procInstId.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="formId"></param>
        /// <returns></returns>
        public async Task<ApplicationDataModel> GetApplicationDataByFormId(int formId)
        {
            return await dbContext.ApplicationData.FirstOrDefaultAsync(p => p.ID == formId);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <param name="currentStatus"></param>
        /// <param name="currentUserID"></param>
        /// <returns></returns>
        public async Task<int> UpdateApplicationCurrentStatus(int procInstId, string currentStatus, string currentUserID)
        {
            string userId = currentUserID.Replace(@"EDPDM\", "");
            var userInfo = await userInfoService.GetUserInfo(userId);
            //var currentUserHandler = $"{userId} {userInfo.UserName}";
            var appData = await dbContext.ApplicationData.FirstOrDefaultAsync(p => p.ProcInstId == procInstId.ToString());
            appData.CurrentStatus = currentStatus;
            appData.CurrentHandler = userId;
            return await dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <param name="currentActivity"></param>
        /// <param name="moduleName"></param>
        /// <param name="functionName"></param>
        /// <returns></returns>
        public async Task<int> UpdateToDoCurrentActivity(int procInstId, string currentActivity, string moduleName, string functionName)
        {
            string funSql = $"select * from [dbo].[ApplicationModuleFunction_v] where ApplicationName='资产管理电子流' and ModuleName =@ModuleName and FunctionName=@FunctionName";
            List<SqlParameter> funSqlParameters = new List<SqlParameter>
            {
                new SqlParameter("ModuleName", moduleName),
                new SqlParameter("FunctionName", functionName),
            };
            var appModuleFun = await edpApplicationContext.ApplicationModuleFunction_v.FromSqlRaw<ApplicationModuleFunction_v>(funSql, funSqlParameters.ToArray()).FirstAsync();
            var functionIDCur = 0;
            if (appModuleFun != null)
            {
                functionIDCur = appModuleFun.FunctionId;
            }

            string sql = $" update dbo.ToDo set CurrentStates =@CurrentStates where FunctionInstanceID=@FunctionInstanceID and FunctionID =@FunctionID";
            List<SqlParameter> sqlParameters = new List<SqlParameter>
            {
                new SqlParameter("CurrentStates", currentActivity),
                new SqlParameter("FunctionInstanceID", procInstId),
                new SqlParameter("FunctionID", functionIDCur)
            };
            return await edpContext.Database.ExecuteSqlRawAsync(sql, sqlParameters);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <param name="functionUrl"></param>
        /// <param name="currentStatus"></param>
        /// <returns></returns>
        public async Task<int> UpdateToDo(int procInstId, string functionUrl, string currentStatus)
        {
            var data = await edpContext.ToDo
                .Where(p => p.FunctionInstanceID == procInstId)
                .OrderByDescending(p => p.ArrivalDate).FirstAsync();

            logger.LogInformation($"SMOService.UpdateToDo,data:{data}");
            
            if (string.IsNullOrEmpty(data.CurrentStates) || string.IsNullOrEmpty(data.FunctionInstanceUrl) )
            {
                string sql = $" UPDATE dbo.ToDo SET CurrentStates =@currentStatus,FunctionInstanceUrl=@functionUrl WHERE FunctionInstanceID=@procInstId and FunctionID =@functionId";
                List<SqlParameter> sqlParameters = new List<SqlParameter>
                {
                    new SqlParameter("currentStatus", currentStatus),
                    new SqlParameter("functionUrl", functionUrl),
                    new SqlParameter("procInstId", procInstId),
                    new SqlParameter("functionId", data.FunctionID)
                };
                return await edpContext.Database.ExecuteSqlRawAsync(sql, sqlParameters);
            }

            return 0;
        }
    }
}
